<?php

/**
 * 递归转义数组的数据
 */
function html_escape($var)
{
    if (is_array($var)) {
        return array_map('esc', $var);
    } else {
        return esc($var);
    }
}

/**
 * 返回成功消息
 */
function success($data = array(), $count = 0, $msg = '操作成功！')
{
    $code = 0;
    $data = html_escape($data);
    $count = intval($count);
    $res = compact('code', 'msg', 'count', 'data');
    exit(json_encode($res, JSON_UNESCAPED_UNICODE));
}

/**
 * 返回失败信息
 */
function error($msg = '操作失败！', $data = array(), $code = 100)
{
    $data = html_escape($data);
    $res = compact('code', 'msg', 'data');
    exit(json_encode($res, JSON_UNESCAPED_UNICODE));
}

/**
 * 格式化文件大小
 */
function humanize_size($size, $func = null)
{
    $map = array(
        0 => 'KB',
        1 => 'MB',
        2 => 'GB',
        3 => 'TB'
    );
    $index = 0;
    if ($size > 1024) {
        do {
            $size = $size / 1024;
            $index ++;
        } while ($size > 1024);
    }
    if (! empty($func) && is_callable($func)) {
        $size = $func($size);
        return "{$size}{$map[$index]}";
    }
    return sprintf("%.02f{$map[$index]}", $size);
}

/**
 * 根据身份证获取出生日期
 */
function getBirthdayByIdCard($certNo, $char = true)
{
    $length = strlen($certNo);
    if ($length == 18) {
        $birthday = substr($certNo, 6, 8);
    } else {
        $birthday = '19' . substr($certNo, 6, 6);
    }
    if ($char) {
        return $birthday[0] . $birthday[1] . $birthday[2] . $birthday[3] . '-' . $birthday[4] . $birthday[5] . '-' . $birthday[6] . $birthday[7];
    }
    // 计算实际年龄
    $initAge = date('Y') - intval($birthday[0] . $birthday[1] . $birthday[2] . $birthday[3]);
    $month = intval($birthday[4] . $birthday[5]);
    if ($month < date('m')) {
        $initAge ++;
    } elseif ($month == date('m') && intval($birthday[6] . $birthday[7]) < date('d')) {
        $initAge ++;
    }
    return $initAge;
}

/**
 * 身份证校验代码
 */
function id_card_verify($id_card)
{
    if (strlen($id_card) == 18) {
        return idcard_checksum18($id_card);
    } elseif ((strlen($id_card) == 15)) {
        $id_card = idcard_15to18($id_card);
        return idcard_checksum18($id_card);
    } else {
        return false;
    }
}

// 18位身份证校验码有效性检查
function idcard_checksum18($idcard)
{
    if (strlen($idcard) != 18) {
        return false;
    }
    $idcard_base = substr($idcard, 0, 17);
    if (idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))) {
        return false;
    } else {
        return true;
    }
}

// 将15位身份证升级到18位
function idcard_15to18($idcard)
{
    if (strlen($idcard) != 15) {
        return false;
    } else {
        // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
        if (array_search(substr($idcard, 12, 3), array(
            '996',
            '997',
            '998',
            '999'
        )) !== false) {
            $idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
        } else {
            $idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
        }
    }
    $idcard = $idcard . idcard_verify_number($idcard);
    return $idcard;
}

// 计算身份证校验码，根据国家标准GB 11643-1999
function idcard_verify_number($idcard_base)
{
    if (strlen($idcard_base) != 17) {
        return false;
    }
    // 加权因子
    $factor = [
        7,
        9,
        10,
        5,
        8,
        4,
        2,
        1,
        6,
        3,
        7,
        9,
        10,
        5,
        8,
        4,
        2
    ];
    // 校验码对应值
    $verify_number_list = [
        '1',
        '0',
        'X',
        '9',
        '8',
        '7',
        '6',
        '5',
        '4',
        '3',
        '2'
    ];
    $checksum = 0;
    for ($i = 0; $i < strlen($idcard_base); $i ++) {
        $checksum += substr($idcard_base, $i, 1) * $factor[$i];
    }
    $mod = $checksum % 11;
    $verify_number = $verify_number_list[$mod];
    return $verify_number;
}
